feat(view): add support for viewing calendar file attachments#33
feat(view): add support for viewing calendar file attachments#33jugarpeupv wants to merge 29 commits intoyousefakbar:mainfrom
Conversation
Detects calendar files by MIME type or extension and attempts to render them using the external script `render-calendar-attachment.py`. If the script is not available, a message is shown with a link to download it. This improves the handling of .ics and similar calendar attachments in the default view handler.
|
I think that a better solution would be to add a config option |
|
Also it looks like a lot of patterns are not anchored while they could be, why is that ? |
|
Fixed anchoring of lua patterns in #35. for pattern, callback in pairs(config.open_handlers) do
if filetype:match(pattern) then
return callback()
end
endbefore the default filetype matching rules. |
|
Hi @jugarpeupv I'm a little cautious of including this. Not sure how I feel about including this script as it has not worked for me when I test it against How does it compare to some other calendar tools like |
|
Hi @yousefakbar, for me it looks like this, i use it to view text/calendar attachments which are commonly meeting invitations
I just wanted a way to see the invitation in a readable format so i can see when it is scheduled Haven't used khal, i ultimately wanted a way to handle meeting mail invitations Haven't tried this tool with .ics files either Maybe it is better to let the user define the handlers for each file type like @anonymousgrasshopper was suggesting |
Formatter fixed mixed indentation (tabs vs spaces) and inconsistent spacing throughout the file to match project style guidelines.
Added documentation for the new optional email address parameter in the :Inbox command, which allows filtering inbox by recipient address with autocomplete support. Updated CHANGELOG.md, README.md, and doc/notmuch.txt to reflect the new functionality.
Replace brittle regex-based text parsing with structured JSON parsing for displaying email threads. This provides more reliable MIME handling and enables new features. Changes: - Add thread.lua module with JSON-based thread processing - Replace `notmuch show | col` with `notmuch show --format=json` - Handle complex MIME structures (multipart/mixed, multipart/alternative) - Concatenate multiple inline text parts (body, signatures, footers) - Show MIME markers for attachments and HTML content New features: - Per-message tag display in thread headers - Attachment count indicator (📎) in message headers - Proper handling of text/plain attachments vs inline content Deprecates util.process_msgs_in_thread() in favor of thread.show_thread()
Add support for rendering HTML email bodies in thread view using w3m. This is useful for multipart/alternative emails where HTML content is often richer than the plain text alternative. - Add `render_html_body` config option (default: false) - Add `render_html()` function with w3m integration - Graceful fallback when w3m is not installed or fails - Fetch HTML content from notmuch with `--include-html` flag - Add module-level documentation to thread.lua
Add `vim.b.notmuch_thread` buffer variable containing thread-level metadata for extensibility (statusline integration, custom scripts). Exported fields: - id: Thread ID for notmuch queries - subject: Thread subject from root message - date_relative: Root message date - message_count: Total messages in thread - tags: Union of all message tags (sorted) - authors: Unique participants (full From header, deduplicated) Implementation: - Accumulate metadata during `build_message_lines()` tree traversal - Return (lines, metadata) tuple from `show_thread()` - Caller sets buffer variable after creating buffer This is the first of several buffer variables that will enable O(1) message lookup and rich statusline integration.
Add `vim.b.notmuch_messages` buffer variable containing an array of
message objects for cursor-to-message lookup and statusline integration.
Each message entry includes:
- id: Message-ID for notmuch queries
- start_line, end_line, fold_line: Line ranges for cursor mapping
- depth: Reply depth in thread
- from, subject, date_relative: Display fields
- tags: Per-message tags array
- attachment_count: Number of attachments
Implementation:
- Track line positions during `build_message_lines()` traversal
- Restructure metadata return as { thread, messages } object
- Caller sets both `vim.b.notmuch_thread` and `vim.b.notmuch_messages`
This enables O(m) message lookup by cursor position, replacing the
O(n) buffer-scanning approach in `util.find_cursor_msg_id()`.
Add `vim.b.notmuch_current` and `vim.b.notmuch_status` buffer variables that automatically update as the cursor moves through the thread. `vim.b.notmuch_current` contains: - All fields from the message at cursor (id, from, tags, etc.) - index: 1-based position in thread - total: total message count `vim.b.notmuch_status` contains a pre-formatted string for statusline: - Format: "2/7 Alice Smith" or "2/7 Alice Smith 📎2" with attachments Implementation: - Add get_message_at_line() for O(m) cursor-to-message lookup - Add update_current_message() to refresh buffer variables - Add setup_cursor_tracking() to create buffer-local CursorMoved autocmd - Fast path optimization skips update if cursor still in same message
Simplifies operations (8 instances) where ID was being fetching the current (cursor) message ID by scanning lines backwards. Instead, we simply reference the `id` field in the buffer-local variable `vim.b.notmuch_current`, which is updated via autocmd on every cursor move event.
…mprovements Adds detail on new thread metadata buffer variables for statusline integration and clarifies the refactored message ID lookup pattern.
Previously, show_thread() only processed json[1][1], assuming a single root node. Threads with multiple depth-0 messages (e.g., orphaned replies, merged threads) were truncated to only the first message. Now iterates over all nodes in json[1] to display the complete thread.
When cursor is at the top of the buffer or in a gap between messages, update_current_message() now falls back to finding the first message whose start_line is after the cursor position. Previously it would clear notmuch_current and notmuch_status, leaving the status bar empty despite messages being present in the thread.
- README: Add w3m as optional dependency, render_html_body config option, and new "Statusline Integration" section with lualine example - Help: Add render_html_body option, w3m dependency, comprehensive buffer-local variables reference (:help notmuch-buffer-variables), and thread.lua module description - CHANGELOG: Note documentation additions
Add changelog entries describing the completion of the major refactoring that removed all Vimscript dependencies and migrated to pure Lua implementation with improved completion filtering.
Remove references to deleted plugin/notmuch.vim and autoload/notmuch.vim files. Reflect command definitions now in init.lua using vim.api.nvim_create_user_command. Update doc/notmuch.txt COMPLETION section to reference the new completion.lua Lua module instead of the old autoload function. Add completion.lua module documentation to the LUA MODULES section describing its purpose and exported functions.
Update TagAdd/TagRm/TagToggle commands in ftplugin files to use the new notmuch.completion.comp_tags Lua function instead of the deprecated notmuch#CompTags Vimscript autoload function. Use customlist completion type for proper handling of Lua table returns.
Introduce a `message_order` config option to control the order of messages displayed in the thread view. Users can choose between "newest-first" and "oldest-first" to suit their preference. When set to "newest-first", the thread view flattens and sorts messages by timestamp in descending order. Default behavior maintains the original hierarchical order.
Introduce a new attachment buffer for compose and reply workflows, modeled after oil.nvim. Users can add, remove, and paste file paths as attachments using intuitive keymaps and commands. The buffer supports direct file path entry, integration with oil.nvim for pasting/yanking, and validates attachments on save. Documentation and syntax highlighting for the new buffer are included. Also refactor attachment commands and sending logic to use the new buffer and improve user feedback.
- Change <Tab> and <S-Tab> in mail thread view to jump to next/previous message using new Lua functions, instead of folding. - When opening a thread, reuse existing buffer only if it has content; otherwise, wipe and reload to avoid stale/empty buffers. - Show subject in thread buffer name for easier switching. - Refreshing a thread buffer now updates it in-place, preserving window state, and updates subject in buffer name if changed. - When opening attachments, if buffer exists, open it in a split. - Add Lua functions to jump to next/previous message in thread.
Add support for rendering image attachments (png, jpg, gif, webp, avif) directly in a floating window using image.nvim, if available. Falls back to the configured view_handler for non-image files or if image.nvim is not installed. Handles image cleanup and window management to avoid stale renders on repeated opens.

Detects calendar files by MIME type or extension and attempts to render them using the external script
render-calendar-attachment.py. If the script is not available, a message is shown with a link to download it. This improves the handling of .ics and similar calendar attachments in the default view handler.https://github.com/ceuk/mutt_dotfiles/blob/master/bin/render-calendar-attachment.py